package org.ysling.litemall.core.task.service;
// Copyright (c) [ysling] [927069313@qq.com]
// [litemall-plus] is licensed under Mulan PSL v2.
// You can use this software according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of Mulan PSL v2 at:
//             http://license.coscl.org.cn/MulanPSL2
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
// See the Mulan PSL v2 for more details.
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.ysling.litemall.core.system.SystemConfig;
import org.ysling.litemall.core.task.GrouponRuleExpiredTask;
import org.ysling.litemall.core.task.OrderCommentTask;
import org.ysling.litemall.core.task.OrderUnconfirmedTask;
import org.ysling.litemall.core.task.OrderUnpaidTask;
import org.ysling.litemall.core.task.service.TaskService;
import org.ysling.litemall.db.domain.LitemallGrouponRules;
import org.ysling.litemall.db.domain.LitemallOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.ysling.litemall.db.service.*;

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.List;

/**
 * 检测订单状态
 */
@Component
public class TaskJob {
    private final Log logger = LogFactory.getLog(TaskJob.class);

    @Autowired
    private LitemallGrouponRulesService rulesService;
    @Autowired
    private LitemallOrderService orderService;
    @Autowired
    private TaskService taskService;

    /**
     * 自动确认收货延时队列检查
     * <p>
     * 定时时间是每天凌晨1点。
     *
     */
    @Scheduled(cron = "0 0 1 * * ?")
    public void checkOrderUnconfirmed() {
        logger.info("系统开始检查延时任务---订单自动确认收货---");
        List<LitemallOrder> orderList = orderService.queryUnconfirmed();
        for(LitemallOrder order : orderList){
            LocalDateTime ship = order.getShipTime();
            LocalDateTime now = LocalDateTime.now();
            LocalDateTime expire =  ship.plusDays(SystemConfig.getOrderUnconfirmed());
            if(expire.isBefore(now)) {
                // 已经过期，则加入延迟队列
                taskService.addTask(new OrderUnconfirmedTask(order.getId(), 0));
            }
            else{
                // 还没过期，则加入延迟队列
                long delay = ChronoUnit.MILLIS.between(now, expire);
                logger.info("订单自动确认收货--超时时间---"+delay);
                taskService.addTask(new OrderUnconfirmedTask(order.getId(), delay));
            }
        }
        logger.info("系统结束检查延时任务---订单自动确认收货---"+orderList.size());
    }

    /**
     * 团购延时队列检查
     * <p>
     * 定时时间是每天凌晨2点。
     *
     */
    @Scheduled(cron = "0 0 2 * * ?")
    public void checkGrouponRuleExpired() {
        logger.info("系统开始检查延时任务---团购规则过期---");
        List<LitemallGrouponRules> grouponRulesList = rulesService.queryExpired();
        for(LitemallGrouponRules grouponRules : grouponRulesList){
            LocalDateTime now = LocalDateTime.now();
            LocalDateTime expire =  grouponRules.getExpireTime();
            if(expire.isBefore(now)) {
                // 已经过期，则加入延迟队列
                taskService.addTask(new GrouponRuleExpiredTask(grouponRules.getId(), 0));
            }
            else{
                // 还没过期，则加入延迟队列
                long delay = ChronoUnit.MILLIS.between(now, expire);
                logger.info("团购规则过期--超时时间---"+delay);
                taskService.addTask(new GrouponRuleExpiredTask(grouponRules.getId(), delay));
            }
        }
        logger.info("系统结束检查延时任务---团购规则过期---"+grouponRulesList.size());
    }

    /**
     * 订单超时支付延时队列检查
     * <p>
     * 定时时间是每天凌晨3点。
     */
    @Scheduled(cron = "0 0 3 * * ?")
    public void checkOrderUnpaid() {
        logger.info("系统开始检查延时任务---订单支付超时---");
        List<LitemallOrder> orderList = orderService.queryUnpaid();
        for(LitemallOrder order : orderList){
            LocalDateTime add = order.getAddTime();
            LocalDateTime now = LocalDateTime.now();
            LocalDateTime expire =  add.plusMinutes(SystemConfig.getOrderUnpaid());
            if(expire.isBefore(now)) {
                // 已经过期，则加入延迟队列
                logger.info("订单支付超时--超时时间---"+0);
                taskService.addTask(new OrderUnpaidTask(order.getId(), 0));
            }
            else{
                // 还没过期，则加入延迟队列
                long delay = ChronoUnit.MILLIS.between(now, expire);
                logger.info("订单支付超时--超时时间---"+delay);
                taskService.addTask(new OrderUnpaidTask(order.getId(), delay));
            }
        }
        logger.info("系统结束检查延时任务---订单支付超时---"+orderList.size());
    }

    /**
     * 可评价订单商品超期
     * <p>
     * 定时时间是每天凌晨4点。
     */
    @Scheduled(cron = "0 0 4 * * ?")
    public void checkOrderComment() {
        logger.info("系统开始检查延时任务---订单评论超时---");
        //查询所有评论超时订单
        List<LitemallOrder> orderList = orderService.queryComment();
        for(LitemallOrder order : orderList){
            LocalDateTime add = order.getConfirmTime();
            LocalDateTime now = LocalDateTime.now();
            LocalDateTime expire =  add.plusDays(SystemConfig.getOrderComment());
            if(expire.isBefore(now)) {
                // 已经过期，则加入延迟队列
                taskService.addTask(new OrderCommentTask(order.getId(), 0));
            }
            else{
                // 还没过期，则加入延迟队列
                long delay = ChronoUnit.MILLIS.between(now, expire);
                logger.info("订单评论超时--超时时间---"+delay);
                taskService.addTask(new OrderCommentTask(order.getId(), delay));
            }
        }
        logger.info("系统结束检查延时任务---订单评论超时---"+orderList.size());
    }
}
